using System;
using System.Collections.Generic;

using Elev.Core.Utility;

namespace Elev.UI
{
    /// <summary>
    /// Singleton class that contains the global variables of the application
    /// </summary>
    public class Globals
    {
        static Globals instance;
        static readonly object padlock = new object();

        ConfigManager cfg;

        int x = 0;
        public int X
        {
            get { return x; }
            set { x = value; }
        }

        int y = 0;
        public int Y
        {
            get { return y; }
            set { y = value; }
        }

        int width = 365;
        public int Width
        {
            get { return width; }
            set { width = value; }
        }

        int height = 345;
        public int Height
        {
            get { return height; }
            set { height = value; }
        }

        string lastSeenDirectory = "";
        public string LastSeenDirectory
        {
            get { return lastSeenDirectory; }
            set { lastSeenDirectory = value; }
        }

        string lastOpenedFile = "";
        public string LastOpenedFile
        {
            get { return lastOpenedFile; }
            set { lastOpenedFile = value; }
        }

        FilesList lastOpenedFiles = new FilesList(5);
        public FilesList LastOpenedFiles
        {
            get { return lastOpenedFiles; }
            set { lastOpenedFiles = value; }
        }

        string language = "FR";
        public string Language
        {
            get { return language; }
            set { language = value; }
        }

        protected Globals()
        {
            cfg = new ConfigManager("Elev");

            x = ensureIntPositive((int)GetValue("X", typeof(int), x), x);
            y = ensureIntPositive((int)GetValue("Y", typeof(int), y), y);
            width = ensureIntPositive((int)GetValue("Width", typeof(int), width), width);
            height = ensureIntPositive((int)GetValue("Height", typeof(int), height), height);
            lastSeenDirectory = (string)GetValue("LastSeenDirectory", typeof(string), lastSeenDirectory);
            lastOpenedFile = (string)GetValue("LastOpenedFile", typeof(string), lastOpenedFile);
            language = (string)GetValue("Language", typeof(string), language);

            string[] s = cfg.GetValues("LastOpenedFiles");
            if (s != null)
                foreach (string str in s)
                    lastOpenedFiles.Add(str);
        }

        static public Globals Get()
        {
            lock (padlock)
            {
                if (instance == null)
                    instance = new Globals();
                return instance;
            }
        }

        public void Save()
        {
            cfg.SetValue("X", x.ToString());
            cfg.SetValue("Y", y.ToString());
            cfg.SetValue("Width", width.ToString());
            cfg.SetValue("Height", height.ToString());
            cfg.SetValue("LastSeenDirectory", lastSeenDirectory);
            cfg.SetValue("LastOpenedFile", lastOpenedFile);
            cfg.SetValues("LastOpenedFiles", lastOpenedFiles.ToArray());
            cfg.SetValue("Language", language);

            cfg.Save();
        }

        object GetValue(string Key, Type type, object DefaultValue)
        {
            string val = cfg.GetValue(Key);
            if (val == "") return DefaultValue;

            return Convert.ChangeType(val, type);
        }

        int ensureIntPositive(int input, int def)
        {
            return (input > 0 ? input : def);
        }
    }

    public class FilesList
    {
        int max;
        List<string> list;

        public FilesList(int MaxNbItems)
        {
            max = MaxNbItems;
            list = new List<string>();
        }

        public void Add(string Item)
        {
            list.Add(Item);
        }

        public void Append(string Item)
        {
            int idx = Contains(Item);
            if (idx > -1)
                list.RemoveAt(idx);
            
            list.Insert(0, Item);
            if (list.Count > max)
                list.RemoveAt(list.Count - 1);
        }

        public string[] ToArray()
        {
            return list.ToArray();
        }

        int Contains(string item)
        {
            for (int i = 0; i < list.Count; i++)
                if (list[i] == item)
                    return i;

            return -1;
        }
    }
}